package sjtu.rfid.rri.services.ale.cyclecontrol;

import java.util.List;
import java.util.concurrent.TimeUnit;

import sjtu.rfid.rri.services.ale.exception.InvalidURIException;
import sjtu.rfid.rri.services.ale.reading.ECReports;
import sjtu.rfid.rri.services.ale.report.ReportBuildNotFoundException;
import sjtu.rfid.rri.services.ale.writing.CCReports;

public interface CycleControlService {

	/**
	 * Submit a cycle control request
	 * 
	 * @param spec
	 *            the cycle control spec, e.g. an ECSpec object
	 * @param type
	 *            the cycle type
	 * @throws CycleControlNotFoundException
	 * @throws ReportBuildNotFoundException
	 */
	void submit(String specName, Object spec, CycleControlType type)
			throws CycleControlNotFoundException, ReportBuildNotFoundException;

	/**
	 * 
	 * @param specName
	 *            the name of the ALE cycle control spec
	 */
	void release(String specName);

	/**
	 * Change the internal state of the cycle control. The actual effect of this
	 * method depends on the operation parameter and the concrete
	 * CycleControlService.
	 * 
	 * @param specName
	 *            the name of the ALE cycle control spec
	 * @param event
	 *            the event which triggers the state change. e.g. Poll
	 */
	void change(String specName, Event event);

	/**
	 * Get the current state of the cycle control.
	 * 
	 * @param specName
	 *            the name of the ALE cycle control spec
	 * @return the current state of the cycle control.
	 */
	String getState(String specName);

	/**
	 * Get a list of Subscribers (notificationURIs).
	 * 
	 * @param specName
	 *            the name of the ALE cycle control spec
	 * @return
	 */
	List<String> getSubscribers(String specName);

	/**
	 * Add a new Subscriber.
	 * 
	 * @param specName
	 *            the name of the ALE cycle control spec
	 * @param notificationURI
	 *            The notificationURI parameter both identifies a specific
	 *            binding of the ALECallback interface and specifies addressing
	 *            information meaningful to that binding.
	 * @throws InvalidURIException
	 */
	void addSubscriber(String specName, String notificationURI)
			throws InvalidURIException;

	/**
	 * Remove the Subscriber.
	 * 
	 * @param specName
	 *            the name of the ALE cycle control spec
	 * @param notificationURI
	 *            The notificationURI parameter both identifies a specific
	 *            binding of the ALECallback interface and specifies addressing
	 *            information meaningful to that binding.
	 * @throws InvalidURIException
	 */
	void removeSubscriber(String specName, String notificationURI)
			throws InvalidURIException;

	/**
	 * A new poll call is outstanding.
	 * 
	 * @param specName
	 *            the name of the ALE cycle control spec
	 */
	void upPollCount(String specName);

	/**
	 * The poll call is no longer outstanding.
	 * 
	 * @param specName
	 *            the name of the ALE cycle control spec
	 */
	void downPollCount(String specName);

	/**
	 * Fetch an ECReports generated by current Active Cycle. <br>
	 * This operation may pending until the Cycle ends or when timeout.
	 * 
	 * @param specName
	 *            the name of the ALE cycle control spec
	 * @param timeout
	 *            the maximum time to wait in milliseconds. <br>
	 *            Specify a value equal or less than zero to wait forever.
	 * @param unit
	 * @return
	 */
	ECReports fetchECReports(String specName, long timeout, TimeUnit unit);

	/**
	 * Fetch a CCReports generated by current Active Cycle. <br>
	 * This operation may pending until the Cycle ends or when timeout.
	 * 
	 * @param specName
	 *            the name of the ALE cycle control spec
	 * @param timeout
	 *            the maximum time to wait in milliseconds. <br>
	 *            Specify a value equal or less than zero to wait forever.
	 * @param unit
	 * @return
	 */
	CCReports fetchCCReports(String specName, long timeout, TimeUnit unit);

}
